/**
 *@Title: SelectorClientTest.java
 *@Description: TODO
 *@author:Lau
 *@date 2017年7月9日 下午7:40:44 
 *@version V1.0
 */
package com.lty.nio.selectortest;

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;


/** 
* @ClassName: SelectorClientTest 
* @Description: NIO选择器实例客户端
* @author Lau 
* @date 2017年7月9日 下午7:40:44 
*  
*/
public class SelectorClientTest {
	private Selector selector;
	private ByteBuffer outBuff = ByteBuffer.allocate(1024);
	private ByteBuffer inBuff = ByteBuffer.allocate(1024);
	private int keys = 0;
	private SocketChannel channel = null;
	
	/***
	 * 
	* @Title: initClient 
	* @Description: 客户端初始化
	* @throws Exception
	* void
	* @throws
	 */
	private void initClient() throws Exception{
		//打开一个SockChannel通道，但未进行连接
		channel = SocketChannel.open();
		
		//打开一个Selector选择器
		selector = Selector.open();
		
		//设置非阻塞
		channel.configureBlocking(false);
		
		//连接服务端
		channel.connect(new InetSocketAddress("127.0.0.1", 8888));
		
		//向selector注册服务端的连接事件
		channel.register(this.selector, SelectionKey.OP_CONNECT);
	}
	
	/** 
	 * @Title: listen 
	 * @Description: 监听服务端事件
	 * void
	 * @throws 
	 */
	private void listen() throws Exception{
		//轮询
		while(true){
			//让选择器至少有一个通道就绪事件
			keys = this.selector.select();
			
			if(keys > 0){
				Iterator<SelectionKey> iterator = this.selector.selectedKeys().iterator();
				while(iterator.hasNext()){
					SelectionKey key = iterator.next();
					//iterator.remove();
					
					//客户端请求连接事件
					if(key.isConnectable()){
						//获取客户端连接通道
						SocketChannel channel = (SocketChannel) key.channel();

						if(channel.isConnectionPending()){
							channel.finishConnect();
							System.out.println("完成连接！");
						}
						
						//向选择器注册读事件
						channel.register(this.selector, SelectionKey.OP_READ);
					}
					else if(key.isReadable()){
						//获取客户端连接通道
						SocketChannel channel = (SocketChannel) key.channel();
						inBuff.clear();
						System.out.println("客户端正在读数据...");
						int len = channel.read(inBuff);
						System.out.println("客户端读取到的数据内容：" + new String(inBuff.array(), 0, len));
						System.out.println("客户端完成数据读取！");
						channel.register(selector, SelectionKey.OP_WRITE);
					}
					else if(key.isWritable()){
						//获取客户端连接通道
						SocketChannel channel = (SocketChannel) key.channel();
						outBuff.clear();
						System.out.println("客户端正在写数据...");
						channel.write(ByteBuffer.wrap("我是 client A, hey!".getBytes()));
						System.out.println("客户端写数据完成！");
					}
				}
			}
			else{
				//System.out.println("client select finished without any keys!");
			}
		}
	}
	
	public void start() throws Exception{
		initClient();
		listen();
	}
	

	public static void main(String[] args) throws Exception {
		new SelectorClientTest().start();
	}
}
